/*      
 **** Client.java ****
Copyright (c) 2008, Dan Crawford, Philip Nichols, Jacob Siegel, Tim Stefanski,
Justin Williamson All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are
permitted provided that the following conditions are met:

Redistributions of source code must retain the above copyright notice, this list of
conditions and the following disclaimer.

Redistributions in binary form must reproduce the above copyright notice, this list
of conditions and the following disclaimer in the documentation and/or other
materials provided with the distribution.

Neither the name of the Artemis Group nor the names of its contributors may be used
to endorse or promote products derived from this software without specific prior
written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
DAMAGE.

Author: Tim
 */
package ALDITS;

import java.io.*;
import java.net.*;
import java.util.Scanner;
import java.util.ArrayList;


public class Client{


	Socket kkSocket = null;
	PrintWriter out = null;
        private TestbedClient GUI;
private int personalScopeRadius;
	public String hostName, userName;
	int playerID ;
	int teamID ;
	
	
	
	public Client(){
                
		super();
                GUI=new TestbedClient(this);
                GUI.setVisible(true);

	}

	public static void main(String[] args) throws IOException{
		Client c = new Client();
                
		
	}
        public static void main2(String[] args) throws IOException{
            Client c = new Client();
        boolean joinedGame;
		do {
			c.askServerName();
			c.connect(c.hostName,2123);
			c.askName();
			joinedGame = c.joinGame();
			if (!joinedGame) {
				System.out.println("Rejected! Please try again");
				System.out.println();
			}
		} while (!joinedGame); //repeat loop until the game is successfully joined
		System.out.println("Joined game hosted at " + c.hostName);
		System.out.println();

		//now that we have joined the game, continue getting lobby updates until the lobby is full
		c.getLobbyUpdate();}
        

	/* Accepts lobby messages until full, calls showLobbyUpdate(), sets players[] */
	public void getLobbyUpdate() {  //($ALDITS004)
		while (true){
			String receivedMsg = "";
			while (true) {
				receivedMsg = MessageManager.recvWithTimeout(this.kkSocket,500); //($ALDITS0015)
				if (receivedMsg.substring(0, 5).equals("lobby")) {
					break;
				}
				else
					System.out.println("TIMEOUT"); //($ALDITS0016)
			}
			String[] result = receivedMsg.split("~");

			Player [] players = null; 
			if (result.length >= 4 ) //if there is at least one person in the lobby..
				players = new Player [(result.length -1 ) / 3];

			int counter = 0;

			for (int j = 1;j < result.length; j+=3) {
				String name = result[j+2];
				int plyrNum = Integer.parseInt(result[j]);
				int teamNum = Integer.parseInt(result [j+1]);
				players[counter++] = new Player(0, 0, plyrNum, teamNum, name);
			}
			showLobbyUpdate(players);
			if (players.length > 7) {//if lobby is full, return
				return;
			}
		}
	}

	public void showLobbyUpdate(Player[] players) {
		System.out.println();
		System.out.println("Current players in Lobby:");
		if (players == null) {
			System.out.println("No one is in here!");
			return;
		}
			for (int j = 0; j < players.length; j++) {
				String name = players[j].getName();
				int plyrNum = players[j].getTeamID();
				int teamNum = players[j].getTeamID();
				System.out.println ("<> {'" + name + "', player " + plyrNum + ", team " + teamNum + "}");
			}
	}
	
	/*      simple console method to enter a user name and assign it to this.userName */ 
	public void askName() { //($ALDITS002)
		System.out.println("Enter user name:");
		Scanner kb = new Scanner(System.in);  

		String name = null;
		if (kb.hasNext()) {
			name = kb.next();
		}
		this.userName = name;
		return;
	}

	/*      simple console method to enter a server name and assign it to this.hostName */
	public void askServerName() { //($ALDITS001)
		System.out.println("Enter server name:");
		Scanner kb = new Scanner(System.in);  

		String name = null;
		if (kb.hasNext()) {
			name = kb.next();
		}
		this.hostName = name;
	}

	public void sendMessage(String m){
		out.println(m);
	}

	public void connect(String host, int port) throws IOException { //($ALDITS003)

		kkSocket = null;
		out = null;
		BufferedReader in = null;

		try {
			kkSocket = new Socket(host, port);
			out = new PrintWriter(kkSocket.getOutputStream(), true);
			in = new BufferedReader(new InputStreamReader(kkSocket.getInputStream()));

		} catch (UnknownHostException e) {
			System.err.println("Don't know about host:"+host);
			System.exit(1);
		} catch (IOException e) {
			System.err.println("Couldn't get I/O for the connection to: "+host+"...port "+port);
			System.exit(1);
		}

		new ClientListenerThread(kkSocket,this).start();
	}

	public void closeDown(){

		try {
			out.close();
			kkSocket.close();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	public boolean joinGame() { //this method is at this point almost psuedocode. Please let me know if this is at all right
		String [] args = {this.userName};
		MessageManager.sendMessage(this.kkSocket, "hi", args);
		String receivedMsg = "";
		while (true) {
			receivedMsg = MessageManager.recvWithTimeout(this.kkSocket,500); //($ALDITS0015)
			if (!receivedMsg.equals("")) {
				break;
			}
		}

		String[] result = receivedMsg.split("~");
		if (receivedMsg.equals(result[0].equals("yo"))) {
			int playerNumber = Integer.parseInt(result[1]);
			int teamNumber = Integer.parseInt(result[2]);
			int playRadius = Integer.parseInt(result[3]);
			int radarRadius = Integer.parseInt(result[4]);
			int wakeWidth = Integer.parseInt(result[5]);
			//not sure what to do with those yet
			return true;
		}
		else { //response is "no"
			return false;
		}
	}

	public void processMessage(String receivedMsg) { //work in progress!
		GUI.LogMsg(receivedMsg);
                String[] result = receivedMsg.split("~");
		if (result.length > 0) {
			String opCode = result[0]; //get the message code (first object in message)

			if (opCode.equals("go")) {
				int count = Integer.parseInt(result[1]);
				//<do something with this info>
			}
			else if (opCode.equals("state")) {
				
			}
			else if (opCode.equals("end")) {
				;
			}
			else if (opCode.equals("land")) {
				;
			}

			else { //invalid message code
				return;
			}

		}
		else {
			return;
		}
	}
}


